/*
 Copyright 2009 Abdulla Abdurakhmanov (abdulla@latestbit.com)
 Original sources are available at www.latestbit.com

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 ISmartBus.h. Created on: 09.06.2009 13:02:32
 */

#ifndef ISMARTBUS_H_
#define ISMARTBUS_H_

#include "smartobjects/SmartObjectsDefs.hpp"
#include "smartobjects/coders/IDataTypesCoder.hpp"
#include "smartobjects/core/IServerInstancesRegistry.hpp"
#include "smartobjects/core/SmartBusClient.hpp"
#include "smartobjects/core/SmartBusServer.hpp"
#include "smartobjects/encrypters/IDataEncrypterFactory.hpp"
#include "smartobjects/network/IEndpointCoordinatorFactory.hpp"
#include "smartobjects/network/IEndpointLocation.hpp"
#include "smartobjects/network/IHandshakeManagerFactory.hpp"
#include "smartobjects/network/IManagedNetwork.hpp"
#include "cpputils/utils/SequenceGenerator.hpp"

namespace smartobjects {

class ISmartBus : public virtual RefObject {

public:
	SO_DLLPRFX virtual ~ISmartBus();

	/**
	 * Get the current data types coder
	 * @return Data Types Coder
	 */
	virtual IDataTypesCoder* createDataTypesCoder() = 0;


    /**
     * Get sequence generator of long values (globally defined for this bus instance)
     * @return Sequence generator of long values
     */
	virtual cpputils::utils::SequenceGenerator<long>& getSequenceGenerator() = 0;

    /**
     * Get current managed network implementation
     * @return Managed Network
     */
	virtual IManagedNetwork* getManagedNetwork() = 0;

    /**
	 * Change default managed network implementation to another (your own implementation)
	 * @param network
	 */
	virtual void setManagedNetwork(IManagedNetwork* network) = 0;

	/**
	 * Connection mode when resolving remote SmartObjects.
	 */
	enum ConnectMode {
			/**
			 * Waiting to connect when resolving IRemoteSmartObject
			 */
			SYNC_CONNECT_MODE,
			/**
			 * Immediately resolve object (without waiting to connect to remote side).
			 * Usually used with subscription on status of IRemoteSmartObject
			 */
			ASYNC_CONNECT_MODE
	};

    /**
     * Set the current connection mode (for resolving remote SmartObjects).
     * Default is SYNC_CONNECT_MODE
     * @param mode a new connection mode
     */
	virtual void setConnectMode(ConnectMode mode) = 0;

    /**
     * Get the current connection mode
     * Default is SYNC_CONNECT_MODE
     * @return current connection mode
     */
	virtual ConnectMode getConnectMode() = 0;

    /**
     * Set timeout to connect to remote side.
     * <i>This timeout is affected only for SYNC_CONNECT_MODE</i>
     * @see ISmartBus.ConnectMode
     * @see #setConnectMode(ConnectMode)
     * @param seconds timeout to connect (in seconds)
     */
	virtual void setSyncConnectTimeout(unsigned long seconds) = 0;

    /**
     * Get the current timeout to connect to remote side.
     * <i>This timeout is affected only for SYNC_CONNECT_MODE</i>
     * @see ISmartBus.ConnectMode
     * @see #setConnectMode(ConnectMode)
     * @return timeout to connect (in seconds)
     */
	virtual unsigned long getSyncConnectTimeout() = 0;

    /**
     * Get shared thread pool
     * @return thread pool
     */
	virtual cpputils::ept::ThreadPool* getThreadPool() = 0;

    /**
     * Get access to registry of server instances of SmartObjects (skeletons & implementations).
     * The registry automatically contains only SmartObjects created & returned from
     * another SmartObject implementations and only if these SmartObjects isn't published manually
     * @return registry of server instances
     */
	virtual IServerInstancesRegistry* getServerInstancesRegistry() = 0;

    /**
     * Create or select already created SmartBusClient which
     * provides client access to specified endpoint location
     * @param location endpoint location
     * @return SmartBusClient
     */
	virtual SmartBusClient* selectBusClient(IEndpointLocation* poLocation) = 0;

    /**
     * Create or select already created SmartBusServer which
     * provides server access on the specified endpoint location (server/port)
     * @param location endpoint location
     * @return SmartBusClient
     */
	virtual SmartBusServer* selectBusServer(IEndpointLocation* poLocation) = 0;


	virtual IEndpointCoordinatorFactory* getCoordinatorFactory() = 0;
	virtual void setCoordinatorFactory(IEndpointCoordinatorFactory* poFactory) = 0 ;

    /**
     * Get access to data encrypter factory, which uses all SmartObjects
     * @return data encrypter factory
     */
	virtual IDataEncrypterFactory* getDataEncrypterFactory() = 0;

    /**
     * Set another implementation of data encrypter factory
     * @param factory data encrypter factory
     */
	virtual void setDataEncrypterFactory(IDataEncrypterFactory* poFactory) = 0;

    /**
     * Set another implementation of handshake manager factory
     * @param handshakeManagerFactory IHandshakeManagerFactory implementation
     */
	virtual void setHandshakeManagerFactory( IHandshakeManagerFactory* poHandshakeManagerFactory ) = 0;

    /**
     * Get handshake manager factory, which uses all connections for handshaking (security/authentication) algorithms
     * @return current handshake manager factory
     */
	virtual IHandshakeManagerFactory* getHandshakeManagerFactory() = 0;

	virtual IEndpointLocation* createEndpointLocation(const std::string& sReferenceURI) = 0;

protected:
	virtual void returnBusClient(SmartBusClient* poClient) = 0;
	virtual void returnBusServer(SmartBusServer* poServer) = 0;

	friend class SmartBusClient;
	friend class SmartBusServer;

};

}

#endif /* ISMARTBUS_H_ */
